﻿using System;
using System.Linq;
using Eflong.Config;
using Eflong.Config.DataFilter;
using Eflong.KJFiles;
using Eflong.MonitoringLib.MonitoringUnit;

namespace Eflong.Convert
{
    public class KJXXNToMonitoring
    {
        public static void KJXXN_DevFileToCoalMineUnitManager( DevFile devFile , ref BaseCoalMineUnit coalMineUnit , int nSysNo , string sPostfix )
        {
            if ( devFile is Kj143DevFiles )
            {
                Kj143FilesToMonitoring.Kj143FilesToCoalMineUnitManager( ( Kj143DevFiles )devFile , ref coalMineUnit , sPostfix );
                return;
            }

            foreach ( var devItem in devFile.dic_DevItem.Values )
            {
                string sId = devItem.SensorNO + sPostfix;

                BaseMonitoringUnit monitoringUint = coalMineUnit.GetMonitoringUnit( sId );
                if ( monitoringUint == null )
                {
                    monitoringUint = new BaseMonitoringUnit( );
                    monitoringUint.nSysNo = nSysNo;
                    coalMineUnit.AddMonitoringUnit( monitoringUint );
                }
                ConvertDevItemToMonitoringUnit( devItem , ref monitoringUint , sPostfix );
                if ( devItem.modifyFlag == ModifyFlags.删除 )
                {
                    monitoringUint.m_bDeleted = true;
                    monitoringUint.m_tmDeleted = devItem.tmModify;
                    monitoringUint.modifyFlag = BaseMonitoringUnit.ModifyFlags.删除;
                }
                else if ( devItem.modifyFlag == ModifyFlags.修改 )
                {
                    monitoringUint.m_bModified = true;
                    monitoringUint.m_tmModified = devItem.tmModify;
                    monitoringUint.modifyFlag = BaseMonitoringUnit.ModifyFlags.修改;
                }
                else if ( devItem.modifyFlag == ModifyFlags.新增 )
                {
                    monitoringUint.m_bAdded = true;
                    monitoringUint.m_tmAdded = devItem.tmModify;
                    monitoringUint.modifyFlag = BaseMonitoringUnit.ModifyFlags.新增;
                }
                else
                {
                    monitoringUint.modifyFlag = BaseMonitoringUnit.ModifyFlags.None;
                }
            }
        }

        public static void KJXXN_DevFileToCoalMineUnitManager( DevFile devFile , ref BaseCoalMineUnit coalMineUnit )
        {
            KJXXN_DevFileToCoalMineUnitManager( devFile , ref coalMineUnit , 1 , "" );
        }

        public static void KJXXN_DevFileToCoalMineUnitManager( DevFile devFile , ref CoalMineUnitManager manager )
        {
            // 匹配矿名称

            string coalName = devFile.Name;
            BaseCoalMineUnit coalMineUnit = manager.GetCoalMineUnitByName( coalName );
            if ( coalMineUnit == null )
            {
                coalMineUnit = new BaseCoalMineUnit( );
                coalMineUnit.m_strName = coalName;
                coalMineUnit.m_nId = 0;
                manager.AddCoalMineUnit( coalMineUnit );
            }
            KJXXN_DevFileToCoalMineUnitManager( devFile , ref coalMineUnit );
        }

        public static void KJXXN_RtDataFileToCoalMineUnitManager( RtData rtData , ref BaseCoalMineUnit coalMineUnit )
        {
            KJXXN_RtDataFileToCoalMineUnitManager( rtData , ref coalMineUnit , 1 , "" );
        }

        public static void KJXXN_RtDataFileToCoalMineUnitManager( RtData rtData , ref BaseCoalMineUnit coalMineUnit , int nSysNo , string sPostfix )
        {
            if ( rtData is Kj143RtData )
            {
                Kj143FilesToMonitoring.KJXXN_RtDataFileToCoalMineUnitManager( ( Kj143RtData )rtData , ref  coalMineUnit , sPostfix );
                return;
            }
            foreach ( var dataItem in rtData.GetDataItems( ) )
            {
                string sId = dataItem.SensorNO + sPostfix;

                BaseMonitoringUnit monitoringUint = coalMineUnit.GetMonitoringUnit( sId );
                if ( monitoringUint != null )
                {
                    ConvertRtDataItemToMonitoringUnit( dataItem , ref monitoringUint );
                }
            }
        }

        public static void KJXXN_RtDataFileToCoalMineUnitManager( RtData rtData , ref CoalMineUnitManager manager )
        {
            string coalName = rtData.Name;
            BaseCoalMineUnit coalMineUnit = manager.GetCoalMineUnitByName( coalName );
            if ( coalMineUnit == null ) return;
            KJXXN_RtDataFileToCoalMineUnitManager( rtData , ref coalMineUnit );
        }

        /// <summary>
        /// 实现监测系统的测点定义向Eflong的联网系统的测点定义转换
        /// </summary>
        /// <param name="devItem"></param>
        /// <param name="monitoringUint"></param>
        public static void ConvertDevItemToMonitoringUnit( DevItem devItem , ref BaseMonitoringUnit monitoringUint , string sPostfix )
        {
            MonitoringUnitType.SensorTypes sensorType = MonitoringUnitType.SensorTypes.模拟量;
            switch ( devItem.SersorType )
            {
                case "模拟量":
                    sensorType = MonitoringUnitType.SensorTypes.模拟量;
                    break;

                case "开关量":
                    sensorType = MonitoringUnitType.SensorTypes.开关量;
                    break;

                case "控制量":
                    sensorType = MonitoringUnitType.SensorTypes.控制量;
                    break;

                case "累计量":
                    sensorType = MonitoringUnitType.SensorTypes.累计量;
                    break;

                default:
                    sensorType = MonitoringUnitType.SensorTypes.模拟量;
                    break;
            }
            monitoringUint.m_strId = devItem.SensorNO + sPostfix;
            if ( devItem.Location.IndexOf( devItem.SersorName ) >= 0 )
            {
                monitoringUint.m_strName = devItem.Location;
            }
            else if ( devItem.SersorName == "甲烷" && devItem.Location.IndexOf( "瓦斯" ) >= 0 )
            {
                monitoringUint.m_strName = devItem.Location;
            }
            else
            {
                monitoringUint.m_strName = devItem.Location;// +devItem.SersorName;
            }
            monitoringUint.LinkageNO = devItem.LinkageNO;
            monitoringUint.CombinedAlarmSet = devItem.CombinedAlarmSet;
            monitoringUint.m_Type = GetConvertType( devItem , ref monitoringUint , ref sensorType );
            if ( sensorType == MonitoringUnitType.SensorTypes.模拟量 )
            {
                monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Analog;

                monitoringUint.m_fLowerBound = StringToFloat( devItem.MeteLowValue );
                monitoringUint.m_fUpperBound = StringToFloat( devItem.MeteUpperValue );
                monitoringUint.m_fLowerLimit = StringToFloat( devItem.AlertLowLimit );
                monitoringUint.m_fUpperLimit = StringToFloat( devItem.AlertUpperLimit );
                monitoringUint.m_fBreakLimit = StringToFloat( devItem.SwitchOffValue );
                monitoringUint.m_fRestLimit = StringToFloat( devItem.SwitchOnValue );
                monitoringUint.EarlyWarningTime = devItem.EarlyWarningTime;
                monitoringUint.EarlyWarningValue = StringToFloat( devItem.EarlyWarningValue );
                if ( monitoringUint.m_Type == MonitoringUnitType.Types.瓦斯 && monitoringUint.m_fUpperBound > 40 && monitoringUint.m_fUpperLimit > 2.5 )
                {
                    //"高浓瓦斯";
                    monitoringUint.m_Type = MonitoringUnitType.Types.高浓瓦斯;
                }
            }
            else if ( sensorType == MonitoringUnitType.SensorTypes.开关量 || sensorType == MonitoringUnitType.SensorTypes.控制量 )
            {
                monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Digital;
            }
            else
            {
                if ( monitoringUint.m_strUnit != "" )
                {
                    monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Analog;
                    monitoringUint.m_fLowerBound = StringToFloat( devItem.MeteLowValue );
                    monitoringUint.m_fUpperBound = StringToFloat( devItem.MeteUpperValue );
                }
                else
                {
                    monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Digital;
                }
            }
        }

        public static MonitoringUnitType.Types GetConvertType( DevItem devItem , ref BaseMonitoringUnit monitoringUint , ref MonitoringUnitType.SensorTypes sensorType )
        {
            return MonitoringUnitType.GetConvertType( devItem.SersorType , devItem.SersorName , devItem.SersorUnit , ref monitoringUint ,
                      ref sensorType );
        }

        public static MonitoringUnitType.Types GetConvertType( string sType , string sensorName , string sensorUnit , ref BaseMonitoringUnit monitoringUint , ref MonitoringUnitType.SensorTypes sensorType )
        {
            MonitoringUnitType.Types type;
            string[ ] strStates = new string[ 3 ];
            string unit = sensorUnit;
            bool m_bTriState = false;
            type = MonitoringUnitType.GetMonitoringUnitTypeByName( sensorName , ref sensorType , ref unit , ref strStates , ref m_bTriState );
            monitoringUint.m_bTriState = m_bTriState;
            if ( sType == "开关量" || sType == "控制量" )
            {
                if ( monitoringUint.m_strStateName == null )
                {
                    monitoringUint.m_strStateName = new string[ 3 ];
                }
                monitoringUint.m_strStateName[ 0 ] = strStates[ 0 ];
                monitoringUint.m_strStateName[ 1 ] = strStates[ 1 ];
                monitoringUint.m_strStateName[ 2 ] = strStates[ 1 ];
            }
            else
            {
                monitoringUint.m_strUnit = unit;
            }
            return type;
        }

        public static void ConvertRtDataItemToMonitoringUnit( string sState , float value , DateTime time , ref BaseMonitoringUnit monitoringUint )
        {
            MonitoringUnitState.States state = MonitoringUnitState.States.UnknownState;

            if ( monitoringUint.m_Modality == MonitoringUnitModality.Modalities.Analog )
            {
                state = ConvertRtDataItemToAnalogMonitoringUnit( sState , value , time , monitoringUint , state );
            }

            else if ( monitoringUint.m_Modality == MonitoringUnitModality.Modalities.Digital )
            {
                state = ConvertRtDataItemToDigitalMonitoringUnit( sState , time , monitoringUint , state );
            }
            else
            {
                MonitoringUnitState.AnalogStates s = MonitoringUnitState.GetAnalogState( sState );
                monitoringUint.m_AnalogState = s;
                state = ( MonitoringUnitState.States )s;
                if ( monitoringUint.m_State != state || monitoringUint.m_timeStateChange.Year < 2000 )
                {
                    monitoringUint.m_timeStateChange = time;
                }
                double d = time.Subtract( monitoringUint.m_timeData ).TotalSeconds;
                if ( monitoringUint.m_fValue != value || d > 5 || monitoringUint.m_timeData.Year < 2009 )
                {
                    monitoringUint.m_fValue = value;
                    monitoringUint.m_timeData = time;
                    monitoringUint.m_bModified = true;
                    monitoringUint.m_State = state;
                }
            }
        }

        private static MonitoringUnitState.States ConvertRtDataItemToDigitalMonitoringUnit( string sState , DateTime time , BaseMonitoringUnit monitoringUint , MonitoringUnitState.States state )
        {
            MonitoringUnitState.DigitalStates s = MonitoringUnitState.GetDigitalState( sState , monitoringUint.m_Type );
            monitoringUint.m_DigitalState = s;
            state = ( MonitoringUnitState.States )s;
            if ( state < MonitoringUnitState.States.Normal )
            {
                if ( monitoringUint.m_State != state || monitoringUint.m_timeStateChange.Year < 2009 )
                {
                    monitoringUint.m_fValue = ( int )state;
                    monitoringUint.m_State = state;
                    monitoringUint.m_timeStateChange = time;
                    monitoringUint.m_timeData = time;
                    monitoringUint.m_bModified = true;
                }
                else
                {
                    double d = time.Subtract( monitoringUint.m_timeData ).TotalSeconds;
                    if ( d > 5 )
                    {
                        monitoringUint.m_timeData = time;
                        monitoringUint.m_bModified = true;
                    }
                }
            }
            else
            {
                if ( monitoringUint.tmFault.Year < 2009 )
                {
                    monitoringUint.tmFault = time;
                }

                double d1 = time.Subtract( monitoringUint.tmFault ).TotalSeconds;

                // 原来状态非中断，且故障时间超过 5秒 或初始状态为中断
                if ( monitoringUint.m_State != MonitoringUnitState.States.Break && d1 > 30 || monitoringUint.m_timeStateChange.Year < 2009 )
                {
                    monitoringUint.m_fValue = 2;
                    monitoringUint.m_timeStateChange = time;
                    monitoringUint.m_State = MonitoringUnitState.States.Break;
                    monitoringUint.tmFault = time;
                    monitoringUint.m_bModified = true;
                }
            }
            return state;
        }

        private static MonitoringUnitState.States ConvertRtDataItemToAnalogMonitoringUnit( string sState , float value , DateTime time , BaseMonitoringUnit monitoringUint , MonitoringUnitState.States state )
        {
            MonitoringUnitState.AnalogStates s = MonitoringUnitState.GetAnalogState( sState );
            monitoringUint.m_AnalogState = s;
            state = ( MonitoringUnitState.States )s;

            if ( state == MonitoringUnitState.States.Normal
                || state == MonitoringUnitState.States.UnderLowerLimit
                || state == MonitoringUnitState.States.OverUpperLimit
                || state == MonitoringUnitState.States.OverBreakLimit
                || state == MonitoringUnitState.States.UnderRestLimit )
            {
                // 判断测点数值是否正常、低于下限、超上限、超断电值

                if ( monitoringUint.m_fLowerLimit < monitoringUint.m_fUpperLimit || monitoringUint.m_fLowerLimit < monitoringUint.m_fBreakLimit )
                {
                    if ( monitoringUint.m_Type == MonitoringUnitType.Types.甲烷 )
                    {
                        // 判断是否超断电值
                        if ( value >= monitoringUint.m_fBreakLimit && monitoringUint.m_fBreakLimit >= monitoringUint.m_fUpperLimit && monitoringUint.m_fBreakLimit > 0.0 )
                        {
                            state = MonitoringUnitState.States.OverBreakLimit;
                        }
                        else if ( value >= monitoringUint.m_fUpperLimit && monitoringUint.m_fUpperLimit > 0.0 )
                        {
                            state = MonitoringUnitState.States.OverUpperLimit;
                        }
                        else
                        {
                            state = MonitoringUnitState.States.Normal;
                        }
                    }
                    else if ( monitoringUint.m_Type == MonitoringUnitType.Types.高浓甲烷 )
                    {
                        // 判断是否超上限
                        if ( value >= monitoringUint.m_fLowerLimit && monitoringUint.m_fLowerLimit > 0 && value < monitoringUint.m_fUpperLimit && monitoringUint.m_fUpperLimit > 0.0 )
                        {
                            state = MonitoringUnitState.States.OverUpperLimit;
                        }
                        else
                        {
                            state = MonitoringUnitState.States.Normal;
                        }
                    }
                    else if ( value >= monitoringUint.m_fUpperLimit && monitoringUint.m_fUpperLimit > 0.0 )
                    {
                        // 判断是否超上限
                        state = MonitoringUnitState.States.OverUpperLimit;
                    }
                    else if ( value >= monitoringUint.m_fLowerLimit && monitoringUint.m_fValue < monitoringUint.m_fUpperLimit )
                    {
                        // 在正常范围
                        state = MonitoringUnitState.States.Normal;
                    }
                    else if ( value < monitoringUint.m_fLowerLimit && ( monitoringUint.m_Type == MonitoringUnitType.Types.负压 || monitoringUint.m_Type == MonitoringUnitType.Types.风速 || monitoringUint.m_Type == MonitoringUnitType.Types.温度 ) )
                    {
                        // 判断是否低于下限
                        state = MonitoringUnitState.States.UnderLowerLimit;
                    }
                }
            }

            if ( monitoringUint.m_State != state || monitoringUint.m_timeStateChange.Year < 2000 )
            {
                monitoringUint.m_timeStateChange = time;
                switch ( state )
                {
                    case MonitoringUnitState.States.OverBreakLimit:
                        monitoringUint.tmBreak = time;
                        break;

                    case MonitoringUnitState.States.OverUpperLimit:
                        monitoringUint.tmAlert = time;
                        break;

                    case MonitoringUnitState.States.OverTiming:
                        monitoringUint.tmTiming = time;
                        break;

                    case MonitoringUnitState.States.UnderLowerLimit:
                        monitoringUint.tmAlert = time;
                        break;

                    case MonitoringUnitState.States.UnderRestLimit:
                        monitoringUint.tmRest = time;
                        break;

                    case MonitoringUnitState.States.Normal:
                        monitoringUint.tmNormal = time;
                        break;
                }
            }
            if ( state >= MonitoringUnitState.States.UnknownState )
            {
                if ( monitoringUint.tmFault.Year < 2009 )
                {
                    monitoringUint.tmFault = time;
                    monitoringUint.m_timeData = time;
                    monitoringUint.m_State = state;
                    monitoringUint.m_fValue = value;
                    monitoringUint.m_bModified = true;
                }
                else
                {
                    if ( monitoringUint.m_State != state )
                    {
                        monitoringUint.m_State = state;
                        monitoringUint.m_fValue = value;
                        monitoringUint.tmFault = time;
                    }
                    double d1 = time.Subtract( monitoringUint.tmFault ).TotalSeconds;
                    double d0 = time.Subtract( monitoringUint.m_timeData ).TotalSeconds;

                    // 原来状态非中断，且故障时间超过 5秒 或初始状态为中断
                    if ( d1 > 30 && d0 > 5 )
                    {
                        monitoringUint.m_bModified = true;
                        monitoringUint.m_timeData = time;
                    }
                }
            }
            else
            {
                double d = time.Subtract( monitoringUint.m_timeData ).TotalSeconds;
                if ( monitoringUint.m_fValue != value || d > 5 || monitoringUint.m_timeData.Year < 2009 )
                {
                    monitoringUint.m_fValue = value;
                    monitoringUint.m_timeData = time;
                    monitoringUint.tmFault = time;
                    monitoringUint.m_bModified = true;
                    monitoringUint.m_State = state;
                }
            }
            return state;
        }

        public static void ConvertRtDataItemToMonitoringUnit( RtDataItem dataItem , ref BaseMonitoringUnit monitoringUint )
        {
            float value = 0;
            value = float.TryParse( dataItem.Value , out value ) ? value : 0;

            // 避免出现四舍五入问题, KJ95N 的数据是 小数点后3位, 例如 0.165， 5.588,0.220,0.250,0.205,
            if ( monitoringUint.m_Type == MonitoringUnitType.Types.瓦斯 && monitoringUint.m_fUpperLimit > value && monitoringUint.m_fUpperLimit - value <= 0.005f )
            {
                value = monitoringUint.m_fUpperLimit;
            }

            else if ( ( monitoringUint.m_Type == MonitoringUnitType.Types.负压 || monitoringUint.m_Type == MonitoringUnitType.Types.风速 || monitoringUint.m_Type == MonitoringUnitType.Types.温度 ) && ( value < monitoringUint.m_fLowerLimit && monitoringUint.m_fLowerLimit - value <= 0.005f ) )
            {
                value = monitoringUint.m_fLowerLimit;
            }

            ConvertRtDataItemToMonitoringUnit( dataItem.State , value , dataItem.Time , ref monitoringUint );
        }

        public static float StringToFloat( string sValue )
        {
            float fValue = 0.0f;
            if ( sValue != "" && sValue != null )
            {
                if ( float.TryParse( sValue , out fValue ) )
                {
                    return fValue;
                }
            }
            return fValue;
        }
    }
}